using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;

namespace AstroX
{
    public class AnalogMux
    {
        AnalogIn ain = null;
        OutputPort s0;
        OutputPort s1;
        OutputPort s2;
        OutputPort s3;
        OutputPort enable;
        int limit = 2;


        public AnalogMux(AnalogIn.Pin signalPin, Cpu.Pin s0Pin, Cpu.Pin s1Pin = Cpu.Pin.GPIO_NONE, Cpu.Pin s2Pin = Cpu.Pin.GPIO_NONE, Cpu.Pin s3Pin = Cpu.Pin.GPIO_NONE, Cpu.Pin enablePin = Cpu.Pin.GPIO_NONE)
        {
            ain = new AnalogIn(signalPin);
            s0 = new OutputPort(s0Pin, false);

            if (s1Pin == Cpu.Pin.GPIO_NONE) { return; }
            s1 = new OutputPort(s1Pin, false);
            limit = limit << 1;

            if (s2Pin == Cpu.Pin.GPIO_NONE) { return; }
            s2 = new OutputPort(s2Pin, false);
            limit = limit << 1;

            if (s3Pin == Cpu.Pin.GPIO_NONE) { return; }
            s3 = new OutputPort(s3Pin, false);
            limit = limit << 1;

            if (enablePin == Cpu.Pin.GPIO_NONE) { return; }
            enable = new OutputPort(enablePin, false);

        }

        public bool Enabled
        {
            get { if (enable == null) { return true; } return enable.Read(); }
            set { enable.Write(value); }
        }

        public int Read(int channel)
        {
            if (channel > limit)
            {
                throw new Exception("Index out of bound for configured mux");
            }

            if ((channel & 0x01) == 1) { s0.Write(true); }
            else { s0.Write(false); }

            if ((channel & 0x02) == 1 && s1 != null) { s1.Write(true); }
            else { s1.Write(false); }

            if ((channel & 0x04) == 1 && s2 != null) { s2.Write(true); }
            else { s2.Write(false); }

            if ((channel & 0x08) == 1 && s3 != null) { s3.Write(true); }
            else { s3.Write(false); }

            return ain.Read();
        }

    }
}
